package net.wofly.sale.stock.web;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import net.wofly.common.util.ExcelUtil;
import net.wofly.right.domain.Organization;
import net.wofly.right.web.RightController;
import net.wofly.sale.commodity.domain.Brand;
import net.wofly.sale.commodity.domain.Commodity;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.ResultCode;
import net.wofly.common.util.ReturnBean;
import net.wofly.common.web.BaseController;
import net.wofly.sale.stock.domain.InStock;
import net.wofly.sale.stock.domain.OutStock;
import net.wofly.sale.stock.domain.Stock;
import net.wofly.sale.stock.domain.StockWarning;
import net.wofly.sale.stock.service.IStockService;
import net.wofly.sale.stock.validator.StockValidator;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by LiuJianbo on 2017/10/14.
 */
@Controller
@RequestMapping(value = "/api/stock")
@Api(description = "库存接口")
public class StockController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(StockController.class);

    private static final String DEFAULT_PAGE_NUM = "1";
    private static final String DEFAULT_PAGE_SIZE = "10";

    @Resource
    IStockService iStockService;


    /**
     * @param inStock
     */
    @ApiOperation(value = "添加库存(入库)", notes = "添加库存(入库)")
    @ApiImplicitParams({@ApiImplicitParam(name = "inStock", value = "入库实体", required = true, dataType = "InStock")})
    @RequestMapping(value = "/addInStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<InStock> addInStock(@RequestBody InStock inStock) {
        ReturnBean<InStock> returnBean;
        String errorMessage = StockValidator.validateAddInStockParams(inStock);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<InStock>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.addInStock(inStock);
        }
        return returnBean;
    }

    /**
     * 添加出库
     * <ul>
     * <li>需要校验库存是否达到预警值</li>
     * </ul>
     *
     * @param outStock
     */
    @ApiOperation(value = "出存", notes = "出存")
    @ApiImplicitParams({@ApiImplicitParam(name = "outStock", value = "出库实体", required = true, dataType = "OutStock")})
    @RequestMapping(value = "/addOutStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<OutStock> addOutStock(@RequestBody OutStock outStock) {
        ReturnBean<OutStock> returnBean;
        String errorMessage = StockValidator.validateAddOutStockParams(outStock);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<OutStock>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.addOutStock(outStock);
        }
        return returnBean;
    }

    /**
     * 校验库存
     * <ul>
     * <li>校验库存是否达到预警值，达到预警值时，需要向消息表中写一条记录</li>
     * </ul>
     *
     * @param warehouseID
     * @param commodityTypeID
     * @param commodityTerminalID
     */
    @ApiOperation(value = "校验库存", notes = "校验库存")
    @ApiImplicitParams({@ApiImplicitParam(name = "warehouseID", value = "仓库ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTypeID", value = "商品ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTerminalID", value = "终端商品ID", required = true, dataType = "String", paramType = "form")})
    @RequestMapping(value = "/checkStockWarning", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<String> checkStockWarning(String warehouseID, String commodityTypeID, String commodityTerminalID) {
        ReturnBean<String> returnBean;
        String errorMessage = StockValidator.validateWarningParams(warehouseID, commodityTypeID,
        		commodityTerminalID);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<String>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.checkStockWarning(warehouseID, commodityTypeID, commodityTerminalID);
        }
        return returnBean;
    }

    /**
     * @param employeeID
     */
    @ApiOperation(value = "获取我的入库单", notes = "获取我的入库单")
    @ApiImplicitParams({@ApiImplicitParam(name = "employeeID", value = "员工ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getMyInStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<InStock>> getMyInStock(
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<InStock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(employeeID);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<PageWrapper<InStock>>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getMyInStock(employeeID, pageNum, pageSize);
        }
        return returnBean;
    }

    /**
     * @param employeeID
     */
    @ApiOperation(value = "获取我的出库单", notes = "获取我的出库单")
    @ApiImplicitParams({@ApiImplicitParam(name = "employeeID", value = "员工ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getMyOutStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<OutStock>> getMyOutStock(
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<OutStock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(employeeID);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<PageWrapper<OutStock>>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getMyOutStock(employeeID, pageNum, pageSize);
        }
        return returnBean;
    }

    /**
     * 获取我的库存
     * <ul>
     * <li>根据传递过来的用户关联仓库查相应的库存</li>
     * <li></li>
     * </ul>
     *
     * @param employeeID
     */
    @ApiOperation(value = "获取我的库存", notes = "获取我的库存")
    @ApiImplicitParams({@ApiImplicitParam(name = "employeeID", value = "员工ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getMyStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<Stock>> getMyStock(
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<Stock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(employeeID);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<PageWrapper<Stock>>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getMyStock(employeeID, pageNum, pageSize);
        }
        return returnBean;
    }
    
    /**
     * 获取全部库存
     * <ul>
     * <li>根据传递过来的用户关联仓库查相应的库存</li>
     * <li></li>
     * </ul>
     *
     * @param employeeID
     */
    @ApiOperation(value = "获取全部库存", notes = "获取全部库存")
    @ApiImplicitParams({@ApiImplicitParam(name = "companyOrgID", value = "公司组织机构ID（传 -1）", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "shopOrgID", value = "店面组织机构ID", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "employeeID", value = "员工ID", required = false, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getAllStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<Stock>> getAllStock(String companyOrgID,String shopOrgID,
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<Stock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(companyOrgID ,shopOrgID ,employeeID );
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<PageWrapper<Stock>>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getAllStock(companyOrgID ,shopOrgID, employeeID, pageNum, pageSize);
        }
        return returnBean;
    }

    @ApiOperation(value = "导出全部库存", notes = "导出全部库存")
    @RequestMapping(value = "/exportAllStock", method = {RequestMethod.GET})
    public void exportAllStock(HttpServletResponse response) {
        ReturnBean<PageWrapper<Stock>> returnBean = iStockService.getAllStock("-1" ,null, null, 1, 10000);
        List<Stock> stockList =  returnBean.getResult() != null ? returnBean.getResult().getContent() : new ArrayList<>();

        XSSFWorkbook wb;
        try {
            String basePath = ResourceUtils.getURL("classpath:").getPath();
            // excel模板路径
            String excel = basePath + "/static/excel/stock.xlsx";
            File fi = new File(excel);
            // 读取excel模板
            wb = new XSSFWorkbook(new FileInputStream(fi));
            // 读取了模板内所有sheet内容
            XSSFSheet sheet = wb.getSheetAt(0);
            // 在相应的单元格进行赋值
            int rowIndex = 1;
            for (Stock stock : stockList) {
                XSSFRow row = sheet.getRow(rowIndex);
                if (null == row) {
                    row = sheet.createRow(rowIndex);
                }

                Commodity commodity = stock.getCommodity();

                ExcelUtil.addCellValueForString(row, 0, commodity.getCommodityCode());
                ExcelUtil.addCellValueForString(row, 1, commodity.getCommodityName());
                ExcelUtil.addCellValueForString(row, 2, commodity.getCapacity());
                ExcelUtil.addCellValueForString(row, 3, commodity.getUnit());
                ExcelUtil.addCellValueForString(row, 4, String.valueOf(commodity.getPrice()));

                ExcelUtil.addCellValueForString(row, 5, String.valueOf(stock.getNum()));
                ExcelUtil.addCellValueForString(row, 6, String.valueOf(stock.getNum() * commodity.getPrice()));
                ExcelUtil.addCellValueForString(row, 7, stock.getCommodityType().getCommodityTypeName());
                ExcelUtil.addCellValueForString(row, 8, stock.getBrand().getBrandName());

                rowIndex++;
            }

            String fileName = "全部库存明细列表";
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            wb.write(os);
            byte[] content = os.toByteArray();
            InputStream is = new ByteArrayInputStream(content);
            // 设置response参数，可以打开下载页面
            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xlsx").getBytes(), "iso-8859-1"));
            ServletOutputStream sout = response.getOutputStream();
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;

            try {
                bis = new BufferedInputStream(is);
                bos = new BufferedOutputStream(sout);
                byte[] buff = new byte[2048];
                int bytesRead;
                // Simple read/write loop.
                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                    bos.write(buff, 0, bytesRead);
                }
            } catch (Exception e) {
                logger.error("导出excel出现异常:", e);
            } finally {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            }

        } catch (Exception e) {
            logger.error("导出excel出现异常:", e);
        }
    }
    
    /**
     * 获取全部入库流水
     * <ul>
     * <li>获取全部入库流水</li>
     * <li></li>
     * </ul>
     *
     * @param employeeID
     */
    @ApiOperation(value = "获取全部入库流水", notes = "获取全部入库流水")
    @ApiImplicitParams({@ApiImplicitParam(name = "companyOrgID", value = "公司组织机构ID（传 -1）", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "shopOrgID", value = "店面组织机构ID", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "employeeID", value = "员工ID", required = false, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getAllInStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<InStock>> getAllInStock(String companyOrgID,String shopOrgID,
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<InStock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(companyOrgID ,shopOrgID ,employeeID );
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getAllInStock(companyOrgID ,shopOrgID, employeeID, pageNum, pageSize);
        }
        return returnBean;
    }
    
    /**
     * 获取全部出库流水
     * <ul>
     * <li>获取全部出库流水</li>
     * <li></li>
     * </ul>
     *
     * @param employeeID
     */
    @ApiOperation(value = "获取全部出库流水", notes = "获取全部出库流水")
    @ApiImplicitParams({@ApiImplicitParam(name = "companyOrgID", value = "公司组织机构ID（传 -1）", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "shopOrgID", value = "店面组织机构ID", required = false, dataType = "String", paramType = "form"),
    			@ApiImplicitParam(name = "employeeID", value = "员工ID", required = false, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getAllOutStock", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<OutStock>> getAllOutStock(String companyOrgID,String shopOrgID,
            String employeeID, @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<OutStock>> returnBean;
        String errorMessage = StockValidator.validateEmployeeID(companyOrgID ,shopOrgID ,employeeID );
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getAllOutStock(companyOrgID ,shopOrgID, employeeID, pageNum, pageSize);
        }
        return returnBean;
    }

    /**
     * @param warehouseID
     * @param commodityTypeID
     * @param commodityTerminalID
     */
    @ApiOperation(value = "分页获取库存预警", notes = "分页获取库存预警")
    @ApiImplicitParams({@ApiImplicitParam(name = "warehouseID", value = "仓库ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTypeID", value = "商品ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTerminalID", value = "终端商品ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "页码（默认第一页）", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示条数（默认10条）", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/getStockWarningByPage", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<PageWrapper<StockWarning>> getStockWarningByPage(
            String warehouseID, String commodityTypeID, String commodityTerminalID,
            @RequestParam(defaultValue = DEFAULT_PAGE_NUM) Integer pageNum,
            @RequestParam(defaultValue = DEFAULT_PAGE_SIZE) Integer pageSize) {
        ReturnBean<PageWrapper<StockWarning>> returnBean;
        String errorMessage = StockValidator.validateWarningParams(warehouseID, commodityTypeID, commodityTerminalID);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<PageWrapper<StockWarning>>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.getStockWarningByPage(warehouseID, commodityTypeID, commodityTerminalID,
                    pageNum, pageSize);
        }
        return returnBean;
    }

    /**
     * @param warehouseID
     * @param commodityTypeID
     * @param commodityTerminalID
     * @param num
     */
    @ApiOperation(value = "设置库存预警", notes = "设置库存预警")
    @ApiImplicitParams({@ApiImplicitParam(name = "warehouseID", value = "仓库ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTypeID", value = "商品ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "commodityTerminalID", value = "终端商品ID", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "num", value = "数量", required = true, dataType = "int", paramType = "form")})
    @RequestMapping(value = "/setStockWarning", method = {RequestMethod.POST})
    @ResponseBody
    public ReturnBean<StockWarning> setStockWarning(
            String warehouseID, String commodityTypeID, String commodityTerminalID, Integer num) {
        ReturnBean<StockWarning> returnBean;
        String errorMessage = StockValidator.validateSetStockWarningParams(warehouseID, commodityTypeID,
        		commodityTerminalID, num);
        if (StringUtils.isNotEmpty(errorMessage)) {
            returnBean = new ReturnBean<StockWarning>(ResultCode.ERROR_DATA, errorMessage);
        } else {
            returnBean = iStockService.setStockWarning(warehouseID, commodityTypeID, commodityTerminalID, num);
        }
        return returnBean;
    }

}
